﻿using Common;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Extensions.Jwt
{
    /// <summary>
    /// JWT权限 认证服务
    /// </summary>
    public static class Authentication_JWTSetup
    {
        public static void AddAuthentication_JWTSetup(this IServiceCollection services)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));

            var symmetricKeyAsBase64 = AppSettings.app(new string[] { "Jwt", "Secret" });
            var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);
            var signingKey = new SymmetricSecurityKey(keyByteArray);
            var Issuer = AppSettings.app(new string[] { "Jwt", "Issuer" });
            var Audience = AppSettings.app(new string[] { "Jwt", "Audience" });
            var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
            // 令牌验证参数
            var tokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = signingKey,
                ValidateIssuer = true,
                ValidIssuer = Issuer,//发行人
                ValidateAudience = true,
                ValidAudience = Audience,//订阅人
                ValidateLifetime = true,
                ClockSkew = TimeSpan.FromSeconds(30),
                RequireExpirationTime = true,
            };

            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)//默认授权机制
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = tokenValidationParameters;

                options.Events = new JwtBearerEvents
                {
                    //权限验证失败后执行
                    OnChallenge = context =>
                    {
                        //终止默认的返回结果(必须有)
                        context.HandleResponse();
                        var result = JsonConvert.SerializeObject(new { Code = "401", Message = "验证失败" });
                        context.Response.ContentType = "application/json";
                        //验证失败返回401
                        context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                        context.Response.WriteAsync(result);
                        return Task.FromResult(0);
                    }
                };
            });

            #region 自定义
            //// 开启Bearer认证
            //services.AddAuthentication(o =>
            //{
            //    o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            //    o.DefaultChallengeScheme = nameof(ApiResponseHandler);
            //    o.DefaultForbidScheme = nameof(ApiResponseHandler);
            //})
            // // 添加JwtBearer服务
            // .AddJwtBearer(o =>
            // {
            //     o.TokenValidationParameters = tokenValidationParameters;
            //     o.Events = new JwtBearerEvents
            //     {
            //         OnChallenge = context =>
            //         {
            //             context.Response.Headers.Add("Token-Error", context.ErrorDescription);
            //             return Task.CompletedTask;
            //         },
            //         OnAuthenticationFailed = context =>
            //         {
            //             var jwtHandler = new JwtSecurityTokenHandler();
            //             var token = context.Request.Headers["Authorization"].ObjToString().Replace("Bearer ", "");

            //             if (token.ObjToString() != "" && jwtHandler.CanReadToken(token))
            //             {
            //                 var jwtToken = jwtHandler.ReadJwtToken(token);

            //                 if (jwtToken.Issuer != Issuer)
            //                 {
            //                     context.Response.Headers.Add("Token-Error-Iss", "issuer is wrong!");
            //                 }

            //                 if (jwtToken.Audiences.FirstOrDefault() != Audience)
            //                 {
            //                     context.Response.Headers.Add("Token-Error-Aud", "Audience is wrong!");
            //                 }
            //             }


            //             // 如果过期，则把<是否过期>添加到，返回头信息中
            //             if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
            //             {
            //                 context.Response.Headers.Add("Token-Expired", "true");
            //             }
            //             return Task.CompletedTask;
            //         }
            //     };
            // })
            // .AddScheme<AuthenticationSchemeOptions, ApiResponseHandler>(nameof(ApiResponseHandler), o => { });


            //基于自定义策略授权
            services.AddAuthorization(options =>
            {
                options.AddPolicy("Admin", policy => policy.RequireRole("Admin").Build());
                //options.AddPolicy("customizePermisson",
                //policy => policy
                //.Requirements
                //.Add(new PermissionRequirement("admin")));
            });

            #endregion


        }
    }
}
